package com.mediacloud.app.newsmodule.fragment.video.x

import android.animation.Animator
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Rect
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.AbsListView
import android.widget.FrameLayout
import android.widget.ListView
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.mediacloud.app.model.OnVideoPause
import com.mediacloud.app.model.OnVideoPlayerPause
import com.mediacloud.app.model.OnVideoPlayerPause2
import com.mediacloud.app.assembly.util.buildUrl
import com.mediacloud.app.model.news.ArticleItem
import com.mediacloud.app.model.news.kt.TypeX
import com.mediacloud.app.newsmodule.R
import com.mediacloud.app.newsmodule.fragment.video.vod.XListPlayer
import com.yoake.media.player.XPlayer
import com.yoake.media.player.controller.component.PrepareView
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import xyz.doikki.videoplayer.player.BaseVideoView
import xyz.doikki.videoplayer.player.VideoView
import java.util.concurrent.atomic.AtomicBoolean

class LVListVideoKit(val context: Context, var listView: ListView,val owner: LifecycleOwner) : BaseVideoView.OnStateChangeListener, LifecycleEventObserver {

    private val playerView: XListPlayer = XListPlayer(context,owner)
    var player: XPlayer = playerView.p
    private var container: FrameLayout? = null
    private var logoView: View? = null
    private var logoAminListener = LogoViewAnimListener()
    private var playerAminListener = PlayerAnimListener()
    private var logoAnim: Animator? = null
    private var playAnim: Animator? = null
    private var pendingExecuteRenderAnimator = AtomicBoolean(false)
    var recordFirstVisibleItem = 0
    var recordVisibleItemCount = 0
    var mDy = 1
    val rect = Rect()
    init {
        if (context is LifecycleOwner) {
            context.lifecycle.addObserver(this)
        }
        player.hidePreparingLoadingView = true
        player.prepareView.fadeOutAnimMoment = PrepareView.FADE_OUT_ANIM_OFF
        EventBus.getDefault().register(this)
        player.addOnStateChangeListener(this)

        listView.setOnScrollListener(object : AbsListView.OnScrollListener{
            override fun onScrollStateChanged(view: AbsListView?, scrollState: Int) {
                if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                    initPendingPlay()
                }
            }

            override fun onScroll(view: AbsListView?, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
                if (firstVisibleItem > recordFirstVisibleItem) {
                    // Log.e("AAACCC", "↓↓↓↓↓↓↓")
                    mDy = 1
                } else if (firstVisibleItem < recordFirstVisibleItem) {
                    //Log.e("AAACCC", "↑↑")
                    mDy = 0
                }
                recordVisibleItemCount = visibleItemCount
                recordFirstVisibleItem = firstVisibleItem
                if (container != null) {
                    container!!.getLocalVisibleRect(rect)
                    if (rect.top != 0 || rect.bottom - rect.top < container!!.measuredHeight) {
                        Log.w("RVLIST", "移除容器 ${container.hashCode()}")
                        release()
                    }
                }
            }
        })

    }


    fun initPendingPlay() {
        container?.let {
            //判断一下当前播放的item是否还处于完全可见状态
            it.getLocalVisibleRect(rect)
            if (rect.top == 0 && rect.bottom - rect.top >= it.measuredHeight) {
                Log.e("AAACCC", "当前播放的item是否还处于完全可见状态")
                return
            }
        }

        if (mDy > 0) {
            for (i in recordFirstVisibleItem until recordFirstVisibleItem + recordVisibleItemCount) {
                Log.e("AAACCC", "${i} ${listView.firstVisiblePosition}")
                if (findPlayingViewHolder(i)) break
            }
        } else {
            for (i in recordFirstVisibleItem + recordVisibleItemCount downTo recordFirstVisibleItem) {
                Log.e("AAACCC", "${i} ${listView.firstVisiblePosition}")
                if (findPlayingViewHolder(i)) break
            }
        }
    }

    private fun findPlayingViewHolder(position: Int): Boolean {
        val view = listView.getChildAt(position - listView.firstVisiblePosition)
        val holder = view?.getTag(R.id.IVideoHolder_ID)
        if (holder is IVideoHolder) {
            holder.getPlayActionView()?.setOnClickListener {
                container = holder.getContainer()
                logoView = holder.getLogLayout()
                holder.getArticle()?.let {
                    intentPlay(it)
                }
            }

            holder.getContainer().getLocalVisibleRect(rect)
            if (rect.top == 0 && rect.bottom - rect.top >= holder.getContainer().measuredHeight) {
                container = holder.getContainer()
                logoView = holder.getLogLayout()
                player.parent?.let {
                    (it as ViewGroup).removeView(player)
                }
                holder.getContainer().addView(player, -1, -1)
                return true
            }
        }
        return false
    }

    fun intentPlay(item: ArticleItem) {
        playerView.parent?.let {
            (it as ViewGroup).removeView(player)
        }
        player.alpha = 0.0f
        player.prepareView.mThumb.visibility = View.GONE
        player.prepareView.playBtn.visibility = View.GONE
        val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
        container?.addView(playerView, 0, params)

        player.setPoster(buildUrl(3,item.logo), ContextCompat.getDrawable(context, R.drawable.cctv7_loading_img))
        when (item.type) {
            TypeX.NEWS.LIVE_VIDEO -> player.setPlayerType(XPlayer.VIDEO_LIVE)
            else -> player.setPlayerType(XPlayer.VIDEO_VOD)
        }
        logoAnim = ObjectAnimator.ofFloat(logoView!!, "alpha", 0f)
        logoAnim?.duration = 500
        logoAnim?.interpolator = null
        logoAnim?.addListener(logoAminListener)
        logoAnim?.start()
        EventBus.getDefault().post(OnVideoPause())
        item.xVideoItem?.let {
            player.addVideoItem(item.xVideoItem, true)
        }
    }

    private fun executeRenderAnimator() {
        pendingExecuteRenderAnimator.set(false)
        playAnim = ObjectAnimator.ofFloat(player, "alpha", 1f)
        playAnim?.duration = 500
        playAnim?.interpolator = null
        playAnim?.addListener(playerAminListener)
        playAnim?.start()
    }

    fun stopPlay() {
        release()
    }

    fun onDestroy() {
        release()
    }

    private fun release() {
        playerView.parent?.let {
            val rl = it as ViewGroup
            rl.removeView(playerView)
        }
        player.release()
        container = null
        logoAnim?.cancel()
        playAnim?.cancel()
        logoView?.alpha = 1f
    }

    override fun onPlayerStateChanged(playerState: Int) {

    }


    override fun onPlayStateChanged(playState: Int) {
        when (playState) {
            VideoView.STATE_BUFFERED -> {
                if (pendingExecuteRenderAnimator.get()) {
                    executeRenderAnimator()
                }
            }
            VideoView.STATE_PLAYING -> {
                if (pendingExecuteRenderAnimator.get()) {
                    executeRenderAnimator()
                }
            }
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onVideoPause(pause: OnVideoPlayerPause) {
        release()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onVideoPause2(pause: OnVideoPlayerPause2) {
        release()
    }

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_PAUSE -> release()
            Lifecycle.Event.ON_DESTROY -> player.release()
        }
    }

    inner class LogoViewAnimListener : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator?) {

        }

        override fun onAnimationEnd(animation: Animator?) {
            if (player.currentPlayState == VideoView.STATE_PLAYING || player.currentPlayState == VideoView.STATE_BUFFERED) {
                executeRenderAnimator()
            } else {
                pendingExecuteRenderAnimator.set(true)
            }
        }

        override fun onAnimationCancel(animation: Animator?) {

        }

        override fun onAnimationRepeat(animation: Animator?) {

        }
    }


    inner class PlayerAnimListener : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator?) {

        }

        override fun onAnimationEnd(animation: Animator?) {
            playerView.bringToFront()
            logoView!!.alpha = 1f
        }

        override fun onAnimationCancel(animation: Animator?) {

        }

        override fun onAnimationRepeat(animation: Animator?) {

        }
    }


}
